#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>

static int major = 101;
static int minor= 0;
static dev_t devno;
struct device *class_dev = NULL;
struct class *cls;

static int hello_open(struct inode *inode, struct file *filep)
{
	printk("hello open() \n");
	return 0;
}

static int hello_release(struct inode *inode, struct file *filep)
{
	printk("hello release() \n");
	return 0;
}

static struct file_operations hello_ops =
{
	.open = hello_open,
	.release = hello_release,
};

static int hello_init(void)
{
	int result = 0;

	printk(KERN_ALERT "hello_init \n");
	devno = MKDEV(major, minor);

	result = register_chrdev(major, "test_dev", &hello_ops);
	if(result < 0) {
		printk("register chardev fail \n");
		return result;
	}

	cls = class_create(THIS_MODULE, "hello_cls");
	if(IS_ERR(cls)) {
		printk("register class create fail \n");
		result	= PTR_ERR(cls);
		unregister_chrdev(major	, "test_dev");
		return result;
	}

	devno = MKDEV(major, minor);
	class_dev = device_create(cls, NULL, devno, NULL, "hello_dev");
	if(IS_ERR(class_dev)) {
		printk("register device create fail \n");
		result	= PTR_ERR(class_dev);
		class_destroy(cls);
	}

	return 0;
}

static void hello_exit(void)
{
	printk(KERN_ALERT "hello_exit \n");
	device_destroy(cls, devno);
	class_destroy(cls);
	unregister_chrdev(major	, "test_dev");
	return;
}

MODULE_LICENSE("Dual BSD/GPL");

module_init(hello_init);
module_exit(hello_exit);
